package com.tanhua.server.service;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.mapper.UserMapper;
import com.tanhua.common.pojo.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

//登入校验
@Service
@Slf4j
public class UserService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Value("${jwt.secret}")
    private String secret;

    //验证码及用户校验
    public String login(String phone, String verificationCode) {
        String redisKey = "CHECK_CODE_" + phone;
        boolean isNew = false;

        //校验验证码
        String redisData = this.redisTemplate.opsForValue().get(redisKey);
       /* String error = JSON.toJSONString(ErrorResult.builder().errCode("005").errMessage("验证码错误!").build());
        System.out.println(error);*/
        if (!StringUtils.equals(verificationCode, redisData)) {
            //  return JSON.toJSONString(ErrorResult.builder().errCode("005").errMessage("验证码错误!").build()); //验证码错误,没规定返回值
            return null;
        }
        //使用完后删除验证码
        redisTemplate.delete("CHECK_CODE_" + phone);

        //验证码校验后通过查看数据库有没有数据来判断有没有注册过,如果为第一次注册user为null
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile", phone);
        User user = userMapper.selectOne(wrapper);
        //判断是否第一次如果是第一次则向数据库注册用户,id自增后mybatis会把id塞到user中即user就有id了
        if (user == null) {
            //创建注册数据
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("123456"));
            //注册新用户
            int insert = this.userMapper.insert(user);
            if (insert == 1) isNew = true;
                //else return JSON.toJSONString(ErrorResult.builder().errCode("006").errMessage("注册失败!").build());
            else {
                log.error("注册失败!");
            }
        }

        //生成token步骤
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id", user.getId());
        // 生成token
        String token = Jwts.builder()
                .setClaims(claims) //存放数据的位置，不能放置敏感数据，如：密码等
                .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .setExpiration(new DateTime().plusHours(12).toDate()) //设置过期时间，12小时后过期
                .compact();

        //发送用户登录成功的消息
        try {
            Map<String, Object> msg = new HashMap<>();
            msg.put("id", user.getId());
            msg.put("date", System.currentTimeMillis());
            rocketMQTemplate.convertAndSend("tanhua-sso-login", msg);
        } catch (MessagingException e) {
            log.error("发送消息失败！", e);
        }

        return token + "|" + isNew;
    }

    //token校验
    public User tokenCheck(String token) {
        Claims body = null;
        try {
            body = Jwts.parser().setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            log.error("token解析错误");
        }
        if (body == null) return null;
        User user = new User();
        //必须通过get拿值
        user.setId(Long.valueOf(body.get("id").toString()));
        return user;
    }
}
